#include "qpagemanager.h"

#include "qpageinfo.h"
#include "xml.h"

#include <QVariant>
#include <QDir>
#include <QFile>
#include <QFileInfo>

using namespace SHAREDLIB;

QPageManager::QPageManager(QObject *parent) :
    QObject(parent),
    m_current(NULL)
{
}

QPageManager::~QPageManager()
{
  qDeleteAll(m_pages);
  m_pages.clear();
}

void QPageManager::addPage(QPageInfo *info)
{
  if(info==NULL || m_pages.contains(info))
  {
      return;
  }
  if(m_current==NULL)
  {
      m_current=info;
  }
  m_pages.append(info);
  QStringList list;
  list=property("oldForms").toStringList();
  list.append(info->get_type()+"/"+info->get_name());
  setProperty("oldForms",list);
  emit addPageSignal(info);
}

int QPageManager::insertPage(QPageInfo *info, int index)
{
    if(info==NULL || m_pages.contains(info))
    {
        return -1;
    }
    if(m_current==NULL)
    {
        m_current=info;
    }
    if(index<0)
    {
        index=m_pages.size();
    }
    m_pages.insert(index,info);
    QStringList list;
    list=property("oldForms").toStringList();
    list.append(info->get_type()+"/"+info->get_name());
    setProperty("oldForms",list);
    emit addPageSignal(info);
    return index;
}

void QPageManager::removePage(QPageInfo *info)
{
    if(info!=NULL)
    {
        m_pages.removeAll(info);
        if(m_current==info)
        {
            if(m_pages.size()>0)
            {
                setCurrentPage(m_pages.first()->get_type(),m_pages.first()->get_name());
            }
            else
            {
                setCurrentPage("","");
            }
        }
        delPageSignal(info);
        delete info;
    }
}

void QPageManager::removePage(const QString &type, const QString &name)
{
  foreach(QPageInfo* info,m_pages)
  {
      if(info->get_type()==type && info->get_name()==name)
      {
          m_pages.removeAll(info);
          if(m_current==info)
          {
              if(m_pages.size()>0)
              {
                  setCurrentPage(m_pages.first()->get_type(),m_pages.first()->get_name());
              }
              else
              {
                  setCurrentPage("","");
              }
          }
          delPageSignal(info);
          delete info;
          return;
      }
  }
}

void QPageManager::removeAt(int index)
{
    if(index<0 || index>=m_pages.size())
    {
        return;
    }
    removePage(m_pages.at(index));
}

QPageInfo* QPageManager::getPage(const QString &type, const QString &name)
{
  foreach(QPageInfo* info,m_pages)
  {
      if(info->get_name()==name && info->get_type()==type)
      {
          return info;
      }
  }
  return NULL;
}

QPageInfo* QPageManager::getPage(int index)
{
  if(index<0 || index>=m_pages.size())
  {
      return NULL;
  }
  return m_pages.at(index);
}

int QPageManager::pageCount()
{
  return m_pages.size();
}

void QPageManager::setCurrentPage(const QString &type, const QString &name)
{
  QPageInfo *info=getPage(type,name);
  if(info!=m_current)
  {
      m_current=info;
      emit currentFormChanged();
  }
}

QPageInfo* QPageManager::getCurrentPage()
{
  return m_current;
}

void QPageManager::load(const QString &projectPath)
{
    clear();
    QString str=projectPath+"/pages.xml";
    QFile f(str);
    if(!f.open(QFile::ReadOnly))
    {
        return;
    }
    QXmlStreamReader r(&f);

    QString name;
    QString type;

    while(!r.atEnd())
    {
        if(r.readNext()==QXmlStreamReader::StartElement)
        {
            if(r.name().toString()=="Page")
            {
                if(readPage(&r,name,type))
                {
                    QString fp=projectPath+"/pages/"+type+"/"+name+".xml";
                    QFile file(fp);
                    if(file.open(QFile::ReadOnly))
                    {
                        QString str=file.readAll();
                        file.close();
                        QXmlStreamReader r(str);
                        XMLObject xml;
                        while(!r.atEnd())
                        {
                            if(r.readNext()==QXmlStreamReader::StartElement)
                            {
                                if(r.name().toString()=="Object")
                                {
                                    xml.read(&r);
                                    break;
                                }
                            }
                        }
                        if(r.hasError())
                        {
                            qDebug(QString("[/pages/%1.xml]: Form file parser falied!").arg(type+"/"+name).toLocal8Bit());

                        }
                        else
                        {
                            QPageInfo *info=new QPageInfo;
                            info->set_name(name);
                            info->set_type(type);
                            info->set_data(str);
                            addPage(info);
                            QStringList list=property("saveForms").toStringList();
                            list.append(name);
                            setProperty("saveForms",list);
                        }
                    }
                    else
                    {
                        qDebug(QString("[/pages/%1.xml]: Form file open falied!").arg(type+"/"+name).toLocal8Bit());
                    }
                }
            }
        }
    }
    f.close();
    emit refresh();
}

bool QPageManager::readPage(QXmlStreamReader *r, QString &name, QString &type)
{
    foreach(const QXmlStreamAttribute &attribute,r->attributes())
    {
        if(attribute.name().toString()=="name")
        {
            name=attribute.value().toString();
        }
        else if(attribute.name().toString()=="type")
        {
            type=attribute.value().toString();
        }
    }

    return (name!="" && type!="");
}

void QPageManager::save(const QString &projectPath)
{
    QString str=projectPath+"/pages.xml";
    QFile f(str);
    if(!f.open(QFile::WriteOnly))
    {
        return;
    }

    QStringList list;
    list=property("oldForms").toStringList();
    QStringList list1;
    foreach(QPageInfo* info,m_pages)
    {
        list1.append(info->get_type()+"/"+info->get_name());
        list.removeAll(info->get_type()+"/"+info->get_name());
    }
    setProperty("oldForms",list1);
    setProperty("saveForms",list1);

    foreach(QString str,list)
    {
        QFile f(projectPath+"/pages/"+str+".xml");
        f.remove();
    }

    QXmlStreamWriter w(&f);
    w.setAutoFormatting(true);
    w.writeStartDocument();
    w.writeStartElement("Pages");
    foreach(QPageInfo* info,m_pages)
    {
        if(info->save(projectPath+"/pages/"))
        {
            w.writeStartElement("Page");
            w.writeAttribute("name",info->get_name());
            w.writeAttribute("type",info->get_type());
            w.writeEndElement();
        }

    }
    w.writeEndElement();
    w.writeEndDocument();
    f.close();
}

void QPageManager::clear()
{
    qDeleteAll(m_pages);
    m_pages.clear();
    m_current=NULL;
    setProperty("oldForms",QStringList());
    setProperty("saveForms",QStringList());
}

void QPageManager::refreshForm()
{
    emit refresh();
}

QList<QPageInfo*> QPageManager::getPages(const QString &type)
{
    QList<QPageInfo*>   list;
    for(int i=0;i<m_pages.size();i++)
    {
        if(m_pages.at(i)->get_type()==type)
        {
            list.append(m_pages.at(i));
        }
    }
    return list;
}
